import cv2
import pandas as pd
import numpy as np
import os

from matplotlib import pyplot as plt


def process_csj(file_path):# CSJ处理逻辑
    columns_csj = ['MMSI', 'Timestamp', 'TimeDelta', 'LATITUDE', 'LONGITUDE', 'SOG', 'Ignore']
    df = pd.read_csv(file_path, sep=' ', names=columns_csj, usecols=['MMSI', 'Timestamp', 'TimeDelta', 'LATITUDE', 'LONGITUDE', 'SOG'])
    df['Timestamp'] = pd.to_datetime(df['Timestamp'], format='%Y%m%d%H%M%S')
    df = df[['MMSI', 'Timestamp', 'LONGITUDE', 'LATITUDE', 'SOG']]  # 按照指定顺序选择列并排除TimeDelta
    return df

def process_zs(file_path, mmsi, subdir):# ZS处理逻辑
    df = pd.read_csv(file_path, usecols=['Date_Time', 'SOG', 'LONGITUDE', 'LATITUDE'])
    if subdir == "2018-4-24":
        df['Date_Time'] += 86400  # 加上一天的秒数
    df.rename(columns={'Date_Time': 'Timestamp'}, inplace=True)
    df['Timestamp'] = pd.to_datetime(df['Timestamp'], unit='s', origin=pd.Timestamp('2018-04-23'))
    df['MMSI'] = mmsi
    df = df[['MMSI', 'Timestamp', 'LONGITUDE', 'LATITUDE', 'SOG']]  # 按照指定顺序选择列并排除TimeDelta
    return df

def process_cfd(file_path, mmsi, subdir):
    # 提取日期中的天数，并转换为对应的秒数（距离2018-06-01的天数乘以每天的秒数）
    day = int(subdir.split('-')[-1])  # 提取日期的天
    seconds_from_start = (day - 1) * 86400  # 从2018-06-01开始的秒数
    # 读取文件内容，手动指定列名（注意这里不再包含MMSI）
    columns_cfd = ['Timestamp', 'TimeDelta', 'LONGITUDE', 'LATITUDE', 'SOG',  'COG', 'WhateverOG Idontknow' ]
    df = pd.read_csv(file_path, names=columns_cfd, usecols=['TimeDelta', 'LONGITUDE', 'LATITUDE', 'SOG'])
    # 调整时间戳
    df['TimeDelta'] += seconds_from_start
    # 将时间戳转换为实际的DateTime
    df['Timestamp'] = pd.to_datetime(df['TimeDelta'], unit='s', origin=pd.Timestamp('2018-06-01'))
    # 由于文件名即MMSI，这里我们添加一个MMSI列，所有行都使用该MMSI值
    df['MMSI'] = mmsi
    df = df[['MMSI', 'Timestamp', 'LONGITUDE', 'LATITUDE', 'SOG']]  # 按照指定顺序选择列并排除TimeDelta
    return df

def plot_and_extract_combined_boundaries(all_trajectories, output_dir, areaname):
    """
    将所有MMSI的轨迹绘制到同一张图上，并提取边界。
    """
    os.makedirs(output_dir, exist_ok=True)  # 确保输出目录存在

    plt.figure(figsize=(10, 8))
    for mmsi, df in all_trajectories.items():
        plt.plot(df['LONGITUDE'], df['LATITUDE'], label=f'MMSI {mmsi}')

    plt.title(f"{areaname}_Trajectories")
    plt.xlabel('Longitude')
    plt.ylabel('Latitude')
    plt.axis('equal')

    # 保存绘制的轨迹图
    combined_trajectory_path = os.path.join(output_dir, f"{areaname}_Trajectories.png")
    plt.savefig(combined_trajectory_path)
    plt.close()

    # 读取保存的轨迹图
    img = cv2.imread(combined_trajectory_path, 0)

    # 应用Canny算法提取边缘
    edges_canny = cv2.Canny(img, 100, 200)
    cv2.imwrite(combined_trajectory_path.replace('_Trajectories.png', '_Canny.png'), edges_canny)

    # 应用Sobel算法提取边缘
    sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
    sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
    edges_sobel = cv2.magnitude(sobelx, sobely)
    cv2.imwrite(combined_trajectory_path.replace('_Trajectories.png', '_Sobel.png'), edges_sobel)

    # 应用Laplacian算法提取边缘
    edges_laplacian = cv2.Laplacian(img, cv2.CV_64F)
    cv2.imwrite(combined_trajectory_path.replace('_Trajectories.png', '_Laplacian.png'), edges_laplacian)


def main():
    dirs = {
        './Data/CSJ': process_csj,
        # './Data/ZS': process_zs,
        # './Data/CFD': process_cfd
    }
    all_trajectories = {}

    for root_dir, process_func in dirs.items():
        if root_dir.endswith('CSJ'):  # CSJ逻辑
            for file_name in os.listdir(root_dir):
                if file_name.endswith('.txt'):
                    file_path = os.path.join(root_dir, file_name)
                    df = process_csj(file_path)
                    # 使用从DataFrame中提取的MMSI作为键来更新all_trajectories字典。这确保了使用文件中实际的MMSI值，而不是文件名来索引轨迹数据。
                    # 确保DataFrame不为空，然后从第一行获取MMSI作为键
                    if not df.empty:
                        # 假设MMSI是DataFrame中的第一列
                        mmsi = df.iloc[0]['MMSI']
                        all_trajectories.setdefault(mmsi, []).append(df)

        elif root_dir.endswith('CFD'):
            for subdir in os.listdir(root_dir):
                subdir_path = os.path.join(root_dir, subdir)
                if os.path.isdir(subdir_path):
                    for file_name in os.listdir(subdir_path):
                        if file_name.endswith('.csv'):
                            file_path = os.path.join(subdir_path, file_name)
                            mmsi = file_name.split('.')[0]
                            df = process_cfd(file_path, mmsi, subdir)
                            all_trajectories.setdefault(mmsi, []).append(df)

        else:  # ZS逻辑，包含子文件夹
            for subdir in os.listdir(root_dir):
                subdir_path = os.path.join(root_dir, subdir)
                if os.path.isdir(subdir_path):
                    for file_name in os.listdir(subdir_path):
                        if file_name.endswith('.csv'):
                            file_path = os.path.join(subdir_path, file_name)
                            mmsi = file_name.split('.')[0]
                            df = process_func(file_path, mmsi, subdir)
                            all_trajectories.setdefault(mmsi, []).append(df)

    # 合并同一MMSI的DataFrame
    for mmsi, dfs in all_trajectories.items():
        all_trajectories[mmsi] = pd.concat(dfs).reset_index(drop=True).sort_values(by='Timestamp')

    output_dir = "./Data/Groups/CSJ/T-SNE_Optics/Trajectory_Outputs"
    plot_and_extract_combined_boundaries(all_trajectories, output_dir, "CSJ")

if __name__ == "__main__":
    main()